package com.coder.bike.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWTPayload;
import com.coder.bike.security.AuthUser;
import com.coder.bike.security.CustomerUserDetailsService;
import com.coder.bike.vo.TokenVo;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassDescription:
 * @JdkVersion: 21
 * @Author: 沈诩宸
 * @Created: 2025/6/5 09:29
 */
@Component
public class LoginUtil {
    private static final Logger log = LoggerFactory.getLogger(LoginUtil.class);

    public static Result authenticateUserByPhone(RedisUtils redisUtils,
                                                 CustomerUserDetailsService userDetailsService,
                                                 String phone) {
        try {
            log.debug("开始手机号认证流程: {}", phone);

            // 直接通过手机号加载用户
            UserDetails userDetails = userDetailsService.loadUserByPhone(phone);
            AuthUser authUser = (AuthUser) userDetails;
            log.debug("用户认证成功: {}", authUser.getUsername());

            // 准备token数据
            Map<String, Object> map = new HashMap<>();
            map.put("username", authUser.getUsername());
            map.put("userid", authUser.getId());
            map.put("userType", authUser.getUserType());

            // 生成token
            String token = JwtUtils.createToken(map);
            log.debug("生成Token成功");

            // 获取token过期时间
            NumberWithFormat claim = (NumberWithFormat) JwtUtils.parseToken(token).getClaim(JWTPayload.EXPIRES_AT);
            long expireTime = Convert.toDate(claim).getTime();

            // 将token存入Redis
            String tokenKey = "token:" + token;
            long nowTime = DateTime.now().getTime();
            redisUtils.set(tokenKey, token, (expireTime - nowTime) / 1000);
            log.debug("Token已存入Redis");

            // 创建认证token并设置到SecurityContext
            UsernamePasswordAuthenticationToken authentication =
                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            log.debug("认证信息已设置到SecurityContext");

            // 返回token信息
            TokenVo tokenVo = new TokenVo();
            tokenVo.setToken(token).setExpireTime(expireTime);
            return Result.success(tokenVo).setMessage("登录成功");
        } catch (Exception e) {
            log.error("手机号认证失败", e);
            return Result.fail().setMessage("认证失败: " + e.getMessage());
        }
    }
    public static Result verifySmsCode(RedisUtils redisUtils, String phoneNumber, String type, String code) {
        String key = "sms:code:" + type + ":" + phoneNumber;
        String correctCode = redisUtils.get(key);

        if (correctCode == null) {
            return Result.fail().setMessage("验证码已过期");
        }

        if (!correctCode.equals(code)) {
            return Result.fail().setMessage("验证码不正确");
        }

        return Result.success();
    }

    public static Result authenticateUser(RedisUtils redisUtils, CustomerUserDetailsService customerUserDetailsService, String username, String password, String userType) {
        try {
            // 使用UserDetailsService加载用户
            UserDetails userDetails = customerUserDetailsService.loadUserByUsername(username);

            // 准备token数据
            Map<String, Object> map = new HashMap<>();
            map.put("username", username);
            map.put("userType", userType);

            // 生成token
            String token = JwtUtils.createToken(map);

            // 获取token过期时间
            NumberWithFormat claim = (NumberWithFormat) JwtUtils.parseToken(token).getClaim(JWTPayload.EXPIRES_AT);
            long expireTime = Convert.toDate(claim).getTime();

            // 将token存入Redis
            String tokenKey = "token:" + token;
            long nowTime = DateTime.now().getTime();
            redisUtils.set(tokenKey, token, (expireTime - nowTime) / 1000);

            // 创建认证token并设置到SecurityContext
            UsernamePasswordAuthenticationToken authentication =
                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 返回token信息
            TokenVo tokenVo = new TokenVo();
            tokenVo.setToken(token).setExpireTime(expireTime);
            return Result.success(tokenVo).setMessage("登录成功");
        } catch (Exception e) {
            return Result.fail().setMessage("认证失败: " + e.getMessage());
        }
    }

}
